import { useEffect, useState, useRef } from 'react';
import { useAuth } from './use-auth';

// 定义Socket接口
interface CustomSocket {
  readyState: number;
  send: (data: string) => void;
  close: () => void;
  addEventListener: (event: string, handler: any) => void;
  removeEventListener: (event: string, handler: any) => void;
  joinProject: (projectId: string) => void;
  leaveProject: (projectId: string) => void;
  sendDocUpdate: (data: any) => void;
  sendCursorPosition: (data: any) => void;
  sendBlockEdit: (data: any) => void;
  on: (event: string, callback: (data: any) => void) => (() => void);
  off: (event: string, callback: (data: any) => void) => void;
}

// 创建一个全局单例Socket实例
let globalSocket: CustomSocket | null = null;
let globalEventHandlers: {[key: string]: Array<(data: any) => void>} = {
  'doc-updated': [],
  'cursor-moved': [],
  'block-editing': [],
  'member-joined': [],
  'member-left': [],
  'connection-error': [],
  'connection-status': []
};

// 连接状态
let isSocketInitialized = false;
let connectionAttempts = 0;
const MAX_RECONNECT_ATTEMPTS = 5;
const RECONNECT_DELAY = 3000;
let isLocalModeEnabled = false; // 本地模式（服务器不可用时）

export function useSocket() {
  const [isConnected, setIsConnected] = useState(false);
  const [connectionState, setConnectionState] = useState<'connecting' | 'connected' | 'disconnected' | 'error'>('disconnected');
  const [error, setError] = useState<Error | null>(null);
  const [inLocalMode, setInLocalMode] = useState(false);
  const reconnectTimeout = useRef<NodeJS.Timeout | null>(null);
  const { user } = useAuth();

  // 触发连接错误事件
  const triggerConnectionError = (errorMessage: string) => {
    console.error('Socket连接错误:', errorMessage);
    setError(new Error(errorMessage));
    setConnectionState('error');
    
    // 广播错误给所有监听器
    globalEventHandlers['connection-error'].forEach(handler => {
      handler({ type: 'server_error', message: errorMessage });
    });
  };

  // 初始化WebSocket连接
  useEffect(() => {
    const initializeSocket = () => {
      // 如果全局Socket已存在，则不再创建
      if (globalSocket && (globalSocket as any).readyState === 1) {
        console.log('WebSocket连接已存在');
        setIsConnected(true);
        setConnectionState('connected');
        return;
      }

      // 如果服务器多次连接失败且达到重试上限，启用本地模式
      if (connectionAttempts >= MAX_RECONNECT_ATTEMPTS) {
        if (!isLocalModeEnabled) {
          isLocalModeEnabled = true;
          setInLocalMode(true);
          console.log('已启用本地模式，不再尝试连接服务器');
          
          // 广播连接状态变化
          globalEventHandlers['connection-status'].forEach(handler => {
            handler({ status: 'local_mode' });
          });
        }
        createLocalModeSocket();
        return;
      }

      // 使用相对路径，将自动匹配当前域名
      const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
      const wsUrl = `${wsProtocol}//${window.location.host}/api/socket`;

      try {
        // 在实际项目中，这应该是真实的WebSocket连接
        // 目前，我们使用模拟连接，但增加了错误处理

        console.log('初始化Socket连接...');
        setConnectionState('connecting');
        
        // 检查我们是否应该模拟服务器错误（用于演示）
        const shouldSimulateError = Math.random() > 0.5;
        
        if (shouldSimulateError) {
          // 模拟服务器错误
          setTimeout(() => {
            triggerConnectionError('server error');
            
            // 尝试重连
            if (connectionAttempts < MAX_RECONNECT_ATTEMPTS) {
              console.log(`连接失败 (${connectionAttempts + 1}/${MAX_RECONNECT_ATTEMPTS})，将在${RECONNECT_DELAY/1000}秒后重试...`);
              reconnectTimeout.current = setTimeout(() => {
                connectionAttempts++;
                initializeSocket();
              }, RECONNECT_DELAY);
            } else {
              console.error('达到最大重连次数，切换到本地模式');
              isLocalModeEnabled = true;
              setInLocalMode(true);
              createLocalModeSocket();
            }
          }, 1000);
        } else {
          // 模拟WebSocket连接成功
          setTimeout(() => {
            createSocket();
    setIsConnected(true);
            setConnectionState('connected');
            connectionAttempts = 0;
            isSocketInitialized = true;
            console.log('Socket连接已建立(模拟)');
            
            // 广播连接状态变化
            globalEventHandlers['connection-status'].forEach(handler => {
              handler({ status: 'connected' });
            });
          }, 1000);
        }
      } catch (err) {
        console.error('初始化Socket错误:', err);
        setError(err as Error);
        setConnectionState('error');
        
        // 尝试重连
        if (connectionAttempts < MAX_RECONNECT_ATTEMPTS) {
          reconnectTimeout.current = setTimeout(() => {
            connectionAttempts++;
            console.log(`尝试重新连接 (${connectionAttempts}/${MAX_RECONNECT_ATTEMPTS})...`);
            initializeSocket();
          }, RECONNECT_DELAY);
        } else {
          console.error('达到最大重连次数，切换到本地模式');
          isLocalModeEnabled = true;
          setInLocalMode(true);
          createLocalModeSocket();
        }
      }
    };

    // 创建标准socket
    const createSocket = () => {
      if (!globalSocket) {
        // 创建自定义Socket实例
        const customSocket: CustomSocket = {
          readyState: 1, // WebSocket.OPEN
          send: (data: string) => {
            console.log('发送数据:', data);
            // 模拟数据发送
            try {
              const parsedData = JSON.parse(data);
              if (parsedData.event && globalEventHandlers[parsedData.event]) {
                // 模拟事件回传到其他客户端
                globalEventHandlers[parsedData.event].forEach(handler => {
                  if (parsedData.data) handler(parsedData.data);
                });
              }
            } catch (e) {
              console.error('发送数据错误:', e);
            }
          },
          close: () => {
            console.log('关闭Socket连接');
            setIsConnected(false);
            setConnectionState('disconnected');
          },
          addEventListener: (event: string, handler: any) => {
            console.log(`添加事件监听: ${event}`);
          },
          removeEventListener: (event: string, handler: any) => {
            console.log(`移除事件监听: ${event}`);
          },
          // 添加自定义方法
          joinProject: (projectId: string) => {
    console.log('加入项目:', projectId);
            // 模拟用户加入通知
            if (user) {
              // 模拟向其他客户端广播用户加入消息
              setTimeout(() => {
                if (globalEventHandlers['member-joined']) {
                  globalEventHandlers['member-joined'].forEach(handler => {
                    handler({
                      projectId,
                      user: {
                        id: user.id,
                        name: user.name || '用户',
                        image: user.image
                      }
                    });
                  });
                }
              }, 500);
            }
          },
          leaveProject: (projectId: string) => {
    console.log('离开项目:', projectId);
            // 模拟用户离开通知
            if (user) {
              // 模拟向其他客户端广播用户离开消息
              if (globalEventHandlers['member-left']) {
                globalEventHandlers['member-left'].forEach(handler => {
                  handler({
                    projectId,
                    userId: user.id
                  });
                });
              }
            }
          },
          sendDocUpdate: (data: any) => {
    console.log('发送文档更新:', data);
            // 模拟向其他客户端广播文档更新
            setTimeout(() => {
              if (globalEventHandlers['doc-updated']) {
                globalEventHandlers['doc-updated'].forEach(handler => {
                  handler(data);
                });
              }
            }, 300);
          },
          sendCursorPosition: (data: any) => {
            // 模拟向其他客户端广播光标位置
            if (globalEventHandlers['cursor-moved']) {
              globalEventHandlers['cursor-moved'].forEach(handler => {
                handler(data);
              });
            }
          },
          sendBlockEdit: (data: any) => {
            console.log('发送块编辑:', data);
            // 模拟向其他客户端广播块编辑状态
            if (globalEventHandlers['block-editing']) {
              globalEventHandlers['block-editing'].forEach(handler => {
                handler(data);
              });
            }
          },
          on: (event: string, callback: (data: any) => void) => {
            if (!globalEventHandlers[event]) {
              globalEventHandlers[event] = [];
            }
            globalEventHandlers[event].push(callback);
            
            // 返回取消订阅函数
            return () => {
              globalEventHandlers[event] = globalEventHandlers[event].filter(cb => cb !== callback);
            };
          },
          off: (event: string, callback: (data: any) => void) => {
            if (globalEventHandlers[event]) {
              globalEventHandlers[event] = globalEventHandlers[event].filter(cb => cb !== callback);
            }
          }
        };
        
        globalSocket = customSocket;
      }
    };
    
    // 创建本地模式socket（不尝试连接服务器）
    const createLocalModeSocket = () => {
      console.log('创建本地模式Socket（离线协作）');
      // 创建本地模式Socket实例
      const localSocket: CustomSocket = {
        readyState: 1, // 设置为已连接，但实际是本地模式
        send: (data: string) => {
          console.log('[本地模式] 发送数据:', data);
        },
        close: () => {
          console.log('[本地模式] 关闭Socket连接');
        },
        addEventListener: () => {},
        removeEventListener: () => {},
        // 本地模式下的方法实现
        joinProject: (projectId: string) => {
          console.log('[本地模式] 项目:', projectId);
        },
        leaveProject: () => {},
        sendDocUpdate: () => {
          console.log('[本地模式] 文档已保存到本地');
        },
        sendCursorPosition: () => {},
        sendBlockEdit: () => {},
        on: (event: string, callback: (data: any) => void) => {
          console.log(`[本地模式] 添加${event}事件监听`);
          return () => {};
        },
        off: () => {}
      };
      
      globalSocket = localSocket;
      setIsConnected(true); // 虽然是本地模式，但是设置为已连接状态
      setConnectionState('connected');
      
      // 广播连接状态变化
      globalEventHandlers['connection-status'].forEach(handler => {
        handler({ status: 'local_mode' });
      });
    };

    // 首次加载时初始化Socket
    if (!isSocketInitialized && !isLocalModeEnabled) {
      initializeSocket();
    }

    // 如果已断开，尝试重连
    if (!isLocalModeEnabled && connectionState === 'disconnected' && connectionAttempts < MAX_RECONNECT_ATTEMPTS) {
      reconnectTimeout.current = setTimeout(() => {
        connectionAttempts++;
        console.log(`尝试重新连接 (${connectionAttempts}/${MAX_RECONNECT_ATTEMPTS})...`);
        initializeSocket();
      }, RECONNECT_DELAY);
    }

    // 组件卸载时清理
    return () => {
      if (reconnectTimeout.current) {
        clearTimeout(reconnectTimeout.current);
      }
    };
  }, [connectionState, user]);

  // 手动重连
  const reconnect = () => {
    if (connectionState !== 'connecting') {
      // 重置本地模式状态
      isLocalModeEnabled = false;
      setInLocalMode(false);
      
      setConnectionState('connecting');
      connectionAttempts = 0;
      isSocketInitialized = false;
      
      // 关闭现有连接
      if (globalSocket) {
        globalSocket.close();
        globalSocket = null;
      }
      
      // 清除重连计时器
      if (reconnectTimeout.current) {
        clearTimeout(reconnectTimeout.current);
      }
      
      // 触发重连逻辑
      setTimeout(() => {
        console.log('手动重连中...');
        
        // 检查是否应该模拟错误（随机）
        const simulateError = Math.random() > 0.7;
        
        if (simulateError) {
          // 模拟服务器错误
          console.error('Socket连接错误: server error');
          setError(new Error('server error'));
          setConnectionState('error');
          
          // 通知所有监听错误的处理器
          globalEventHandlers['connection-error'].forEach(handler => {
            handler({ 
              type: 'server_error', 
              message: 'server error' 
            });
          });
          
          return;
        }
        
        // 创建自定义Socket实例
        const customSocket: CustomSocket = {
          readyState: 1, // WebSocket.OPEN
          send: (data: string) => {
            console.log('发送数据:', data);
            // 模拟数据发送
          },
          close: () => {
            console.log('关闭Socket连接');
            setIsConnected(false);
            setConnectionState('disconnected');
          },
          addEventListener: (event: string, handler: any) => {
            console.log(`添加事件监听: ${event}`);
          },
          removeEventListener: (event: string, handler: any) => {
            console.log(`移除事件监听: ${event}`);
          },
          // 添加自定义方法
          joinProject: (projectId: string) => {
            console.log('加入项目:', projectId);
          },
          leaveProject: (projectId: string) => {
            console.log('离开项目:', projectId);
          },
          sendDocUpdate: (data: any) => {
            console.log('发送文档更新:', data);
          },
          sendCursorPosition: (data: any) => {
            // 静默发送
          },
          sendBlockEdit: (data: any) => {
            console.log('发送块编辑:', data);
          },
          on: (event: string, callback: (data: any) => void) => {
            if (!globalEventHandlers[event]) {
              globalEventHandlers[event] = [];
            }
            globalEventHandlers[event].push(callback);
            return () => {
              globalEventHandlers[event] = globalEventHandlers[event].filter(cb => cb !== callback);
            };
          },
          off: (event: string, callback: (data: any) => void) => {
            if (globalEventHandlers[event]) {
              globalEventHandlers[event] = globalEventHandlers[event].filter(cb => cb !== callback);
            }
          }
        };
        
        globalSocket = customSocket;
        
        setIsConnected(true);
        setConnectionState('connected');
        isSocketInitialized = true;
        console.log('Socket连接已重新建立(模拟)');
        
        // 广播连接状态变化
        globalEventHandlers['connection-status'].forEach(handler => {
          handler({ status: 'connected' });
        });
      }, 1500);
    }
  };

  // 强制切换到本地模式
  const switchToLocalMode = () => {
    // 如果已经在本地模式，不需要重复切换
    if (inLocalMode) return;
    
    console.log('手动切换到本地模式');
    isLocalModeEnabled = true;
    setInLocalMode(true);
    
    // 关闭现有连接
    if (globalSocket) {
      globalSocket.close();
      globalSocket = null;
    }
    
    // 创建本地模式Socket实例
    const localSocket: CustomSocket = {
      readyState: 1, // 设置为已连接，但实际是本地模式
      send: (data: string) => {
        console.log('[本地模式] 发送数据:', data);
      },
      close: () => {
        console.log('[本地模式] 关闭Socket连接');
      },
      addEventListener: () => {},
      removeEventListener: () => {},
      joinProject: (projectId: string) => {
        console.log('[本地模式] 项目:', projectId);
      },
      leaveProject: () => {},
      sendDocUpdate: () => {
        console.log('[本地模式] 文档已保存到本地');
      },
      sendCursorPosition: () => {},
      sendBlockEdit: () => {},
      on: (event: string, callback: (data: any) => void) => {
        console.log(`[本地模式] 添加${event}事件监听`);
    return () => {};
      },
      off: () => {}
    };
    
    globalSocket = localSocket;
    setIsConnected(true);
    setConnectionState('connected');
    
    // 广播连接状态变化
    globalEventHandlers['connection-status'].forEach(handler => {
      handler({ status: 'local_mode' });
    });
  };

  return {
    isConnected,
    connectionState,
    error,
    socket: globalSocket,
    inLocalMode,
    joinProject: (projectId: string) => globalSocket?.joinProject(projectId),
    leaveProject: (projectId: string) => globalSocket?.leaveProject(projectId),
    sendDocUpdate: (data: any) => globalSocket?.sendDocUpdate(data),
    sendCursorPosition: (data: any) => globalSocket?.sendCursorPosition(data),
    sendBlockEdit: (data: any) => globalSocket?.sendBlockEdit(data),
    // Ensure on is always a function, even when globalSocket is null
    on: (event: string, callback: (data: any) => void) => {
      // If globalSocket exists, use its on method
      if (globalSocket && typeof globalSocket.on === 'function') {
        return globalSocket.on(event, callback);
      }
      // Otherwise return a no-op function
      console.warn(`Socket not connected, registering ${event} handler for later`);
      // Add the callback to global handlers for when socket connects
      if (!globalEventHandlers[event]) {
        globalEventHandlers[event] = [];
      }
      globalEventHandlers[event].push(callback);
      return () => {
        // Remove handler when unsubscribed
        if (globalEventHandlers[event]) {
          globalEventHandlers[event] = globalEventHandlers[event].filter(cb => cb !== callback);
        }
      };
    },
    off: (event: string, callback: (data: any) => void) => {
      if (globalSocket && typeof globalSocket.off === 'function') {
        globalSocket.off(event, callback);
      }
      // Also remove from global handlers
      if (globalEventHandlers[event]) {
        globalEventHandlers[event] = globalEventHandlers[event].filter(cb => cb !== callback);
      }
    },
    reconnect,
    switchToLocalMode
  };
}